#ifndef _HY_HANDLE_ACCEPT_H_
#define _HY_HANDLE_ACCEPT_H_

#ifdef _WIN32
#include <WinSock2.h>
#include <MSWSock.h>
#include <Windows.h>
#include <process.h>

static const int c_pre_sockets = 20;
static LPFN_ACCEPTEX lpfnAcceptEx = NULL;
static LPFN_GETACCEPTEXSOCKADDRS lpfnGetAcceptExSockAddrs = NULL;
static GUID GuidAcceptEx = WSAID_ACCEPTEX;
static GUID GuidGetAcceptExSockAddrs = WSAID_GETACCEPTEXSOCKADDRS;

//for pre-accept socket
struct hy_accept_iocp_data: public hy_iocp_data
{
	void reset()
	{
		hy_iocp_data::reset();
		_accept = HY_INVALID_SOCKET;
		memset(_addr,0,((sizeof(SOCKADDR_IN)+16)*2));
	}
	hy_socket_t _accept;
	char _addr[((sizeof(SOCKADDR_IN)+16)*2)];
};
#endif


class hy_handle_accept : public hy_handle_base
{
public:
	hy_handle_accept();
	virtual ~hy_handle_accept();

	//*************************************************************************
	// Method:    hy_handle_accept::init
	// Returns:   hy_err_t
	// Parameter: hy_reactor_base * reactor
	// Parameter: hy_accept_tactics * accept
	// Qualifier:
	//*************************************************************************
	hy_err_t init(hy_reactor_base* reactor,hy_accept_tactics* accept);

	//*************************************************************************
	// Method:    hy_handle_accept::open
	// Returns:   hy_err_t
	// Parameter: const char * addr
	// Parameter: hy_u32_t port
	// Qualifier:
	//*************************************************************************
	virtual hy_err_t open(const char* addr,hy_u32_t port);


	//*************************************************************************
	// Method:    hy_handle_accept::handle_accept
	// Returns:   void
	// Parameter: hy_i32_t bytes
	// Qualifier:
	//*************************************************************************
	virtual void handle_input(hy_i32_t bytes);
	//************************************
	// Method:    handle_output
	// FullName:  hy_handle_accept::handle_output
	// Access:    public 
	// Returns:   void
	// Qualifier:
	// Parameter: hy_i32_t bytes
	//************************************
	virtual void handle_output(hy_i32_t bytes);
	//*************************************************************************
	// Method:    hy_handle_accept::handle_error
	// Returns:   void
	// Qualifier:
	//*************************************************************************
	virtual void handle_error();

	//*************************************************************************
	// Method:    hy_handle_accept::close
	// Returns:   void
	// Qualifier:
	//*************************************************************************
	virtual void close();

private:

	hy_accept_tactics*		_accept;

	hy_err_t iocp_open();
	hy_err_t post_accept( int index );

#ifdef _WIN32
	hy_accept_iocp_data*	_sockets[c_pre_sockets];
#endif
};

#endif  //_HY_HANDLE_ACCEPT_H_
